package com.xinwangai.jingbai.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xinwangai.jingbai.common.exception.BusinessException;
import com.xinwangai.jingbai.mapper.CheckinMapper;
import com.xinwangai.jingbai.pojo.DTO.CheckinActivityDTO;
import com.xinwangai.jingbai.pojo.VO.*;
import com.xinwangai.jingbai.service.CheckinService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 简化版打卡系统服务实现类
 * 移除子打卡概念，只保留主打卡活动
 *
 * @author guo.wenliang
 * @since 2025/7/16 20:45
 */
@Service
public class CheckinServiceImpl implements CheckinService {

    @Autowired
    private CheckinMapper checkinMapper;

    // ============= 打卡活动相关方法 =============

    @Override
    public int createCheckinActivity(CheckinActivity checkinActivity) {
        checkinActivity.setCreateTime(new Date());
        checkinActivity.setUpdateTime(new Date());
        return checkinMapper.insertCheckinActivity(checkinActivity);
    }

    @Override
    public int updateCheckinActivity(CheckinActivity checkinActivity) {
        checkinActivity.setUpdateTime(new Date());
        return checkinMapper.updateCheckinActivity(checkinActivity);
    }

    @Override
    public int deleteCheckinActivity(Long id, Long userId) {
        // 检查权限
        CheckinActivity activity = checkinMapper.getCheckinActivityById(id);
        if (activity == null || !activity.getCreatedBy().equals(userId)) {
            return 0;
        }

        // 手动删除相关打卡记录（不使用外键级联删除）
        // 使用批量删除提高效率
        checkinMapper.deleteCheckinRecordsByActivity(id);

        // 删除活动
        return checkinMapper.deleteCheckinActivity(id);
    }

    @Override
    public PageInfo<CheckinActivity> getCheckinActivities(CheckinActivityDTO checkinActivityDTO) {
        // 获取总数
        PageHelper.startPage(checkinActivityDTO.getPageNum(), checkinActivityDTO.getPageSize());

        // 获取分页数据
        List<CheckinActivity> list = checkinMapper.getCheckinActivities(checkinActivityDTO);

        PageInfo<CheckinActivity> pageInfo = new PageInfo<>(list);

        return pageInfo;
    }

    @Override
    public CheckinActivity getCheckinActivityDetail(Long id) {
        CheckinActivity activity = checkinMapper.getCheckinActivityById(id);
        if (activity != null) {
            // 计算活动进度
            int completedDays = checkinMapper.countCompletedDaysByActivity(id);
            activity.setCompletedDays(completedDays);

            // 计算进度百分比
            if (activity.getTargetDays() > 0) {
                double progress = (double) completedDays / activity.getTargetDays() * 100;
                // 这里可以设置进度字段，如果VO中有的话
            }
        }
        return activity;
    }

    // ============= 打卡记录相关方法 =============

    @Override
    public int createCheckinRecord(CheckinRecord checkinRecord) {
        // 验证活动是否存在（不使用外键约束）
        CheckinActivity activity = checkinMapper.getCheckinActivityById(checkinRecord.getActivityId());
        if (activity == null) {
            throw new BusinessException("活动不存在");
        }

        // 检查是否已经打卡（不使用唯一约束）
        Integer count = checkinMapper.checkDailyCheckin(checkinRecord);
        if (count > 0) {
            throw new BusinessException("今天已经打卡过了");
        }

        // 插入打卡记录
        int result = checkinMapper.insertCheckinRecord(checkinRecord);

//        if (result > 0) {
//            // 更新活动进度
//            updateActivityProgress(checkinRecord.getActivityId());
//        }

        return result;
    }

    @Override
    public int updateCheckinRecord(Long id, String status, String notes, Integer duration, Long userId) {
        CheckinRecord record = checkinMapper.getCheckinRecordById(id);
        if (record == null || !record.getUserId().equals(userId)) {
            return 0;
        }
        record.setNotes(notes);

        return checkinMapper.updateCheckinRecord(record);
    }

    @Override
    public int deleteCheckinRecord(Long id, Long userId) {
        CheckinRecord record = checkinMapper.getCheckinRecordById(id);
        if (record == null || !record.getUserId().equals(userId)) {
            return 0;
        }
        return checkinMapper.deleteCheckinRecord(id);
    }

    @Override
    public PageResult<CheckinRecord> getCheckinRecords(Long activityId, Long userId, String startDate, String endDate, Integer pageNum, Integer pageSize) {
        int offset = (pageNum - 1) * pageSize;

        int total = checkinMapper.countCheckinRecords(activityId, userId, startDate, endDate);
        List<CheckinRecord> list = checkinMapper.getCheckinRecords(activityId, userId, startDate, endDate, offset, pageSize);

        return new PageResult<>(list, total, pageNum, pageSize);
    }

    // ============= 统计相关方法 =============

    @Override
    public Map<String, Integer> getCheckinCalendar(Long userId, String year, String month, Long activityId) {
        Map<String, Integer> calendarData = new HashMap<>();

        if (activityId != null) {
            // 获取活动信息
            CheckinActivity activity = checkinMapper.getCheckinActivityById(activityId);
            if (activity != null) {
                // 根据活动类型和频率生成可打卡日期
                List<String> availableDates = generateAvailableDates(activity, year, month);

                // 获取实际打卡记录
                List<Map<String, Object>> calendarList = checkinMapper.getCheckinCalendarData(userId, year, month, activityId);
                Map<String, Integer> actualCheckins = new HashMap<>();
                for (Map<String, Object> item : calendarList) {
                    String date = (String) item.get("date");
                    Long countLong = (Long) item.get("count");
                    actualCheckins.put(date, countLong != null ? countLong.intValue() : 0);
                }

                // 合并数据：可打卡日期 + 实际打卡次数
                for (String date : availableDates) {
                    calendarData.put(date, actualCheckins.getOrDefault(date, 0));
                }
            }
        }
        else {
            // 没有指定活动时，显示所有打卡记录
            List<Map<String, Object>> calendarList = checkinMapper.getCheckinCalendarData(userId, year, month, activityId);
            for (Map<String, Object> item : calendarList) {
                String date = (String) item.get("date");
                Long countLong = (Long) item.get("count");
                Integer count = countLong != null ? countLong.intValue() : 0;
                calendarData.put(date, count);
            }
        }

        return calendarData;
    }

    /**
     * 根据活动类型和频率生成可打卡日期
     */
    private List<String> generateAvailableDates(CheckinActivity activity, String year, String month) {
        List<String> availableDates = new ArrayList<>();
        LocalDate startDate = activity.getStartDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate endDate = activity.getEndDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

        int targetYear = Integer.parseInt(year);
        int targetMonth = Integer.parseInt(month);
        int frequency = activity.getCheckinFrequency() != null ? activity.getCheckinFrequency() : 1;

        // 统一按频率生成可打卡日期
        LocalDate current = startDate;
        int dayCount = 0;

        while (!current.isAfter(endDate)) {
            if (current.getYear() == targetYear && current.getMonthValue() == targetMonth) {
                if (dayCount % frequency == 0) {
                    availableDates.add(current.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                }
                dayCount++;
            }
            current = current.plusDays(1);
        }

        return availableDates;
    }

    @Override
    public CheckinStats getCheckinStats(Long userId, Long activityId) {
        CheckinStats stats = checkinMapper.getUserCheckinStats(userId, activityId);
        if (stats != null) {
            // 使用应用层计算连续打卡天数
            stats.setCurrentStreak(calculateStreak(userId));

            // 计算完成率
            if (stats.getTotalActivities() > 0) {
                double rate = (double) stats.getActiveActivities() / stats.getTotalActivities() * 100;
                stats.setCompletionRate(Math.round(rate * 100.0) / 100.0);
            }

            // 计算最长连续打卡天数（简化版，可以后续优化）
            stats.setLongestStreak(stats.getCurrentStreak());
        }
        return stats;
    }

    @Override
    public Map<String, Object> getDashboardStats(Long userId) {
        Map<String, Object> stats = checkinMapper.getDashboardStats(userId);
        if (stats != null) {
            // 添加连续打卡天数
            stats.put("currentStreak", calculateStreak(userId));
        }
        return stats;
    }

    // ============= 参与者相关方法 =============

    @Override
    public int addParticipants(Long activityId, List<String> participants) {
        return checkinMapper.addParticipants(activityId, participants);
    }

    @Override
    public int removeParticipant(Long activityId, String participant) {
        return checkinMapper.removeParticipant(activityId, participant);
    }

    @Override
    public List<String> getParticipants(Long activityId) {
        return checkinMapper.getParticipants(activityId);
    }

    @Override
    public int joinActivity(Long activityId, Long userId, String userName) {
        // 获取活动信息用于冗余存储
        CheckinActivity activity = checkinMapper.getCheckinActivityById(activityId);
        if (activity == null) {
            throw new RuntimeException("活动不存在");
        }

        // 使用更新后的Mapper方法，传递活动信息
        return checkinMapper.joinActivity(activityId, activity.getTitle(), userId, userName);
    }

    @Override
    public int leaveActivity(Long activityId, Long userId) {
        return checkinMapper.leaveActivity(activityId, userId);
    }

    /**
     * 更新活动进度（应用层处理，不使用触发器）
     */
    private void updateActivityProgress(Long activityId) {
        CheckinActivity activity = checkinMapper.getCheckinActivityById(activityId);
        if (activity != null) {
            // 计算已完成天数
            int completedDays = checkinMapper.countCompletedDaysByActivity(activityId);
            activity.setCompletedDays(completedDays);

            // 更新状态
            if (activity.getTargetDays() > 0) {
                double progress = (double) completedDays / activity.getTargetDays() * 100;
            }

            // 更新参与人数（计算不重复的用户数）
            List<CheckinRecord> allRecords = checkinMapper.getCheckinRecords(activityId, null, null, null, 0, Integer.MAX_VALUE);
            long participantCount = allRecords.stream()
                    .map(CheckinRecord::getUserId)
                    .distinct()
                    .count();
            activity.setTotalParticipants((int) participantCount);

            activity.setUpdateTime(new Date());
            checkinMapper.updateCheckinActivity(activity);
        }
    }

    /**
     * 计算连续打卡天数
     */
    private int calculateStreak(Long userId) {
        List<CheckinRecord> records = checkinMapper.getCheckinRecordsByUser(userId);
        if (records.isEmpty()) {
            return 0;
        }



        return 0;
    }
}
